﻿using System.Collections;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;
using Volo.Abp.Linq;
using YAPACS.BusinessObjects.Exams;
using YAPACS.BusinessObjects.Managements.Exams;
using YAPACS.Organizations;
using YAPACS.RisServer.Abstractions;
using YAPACS.Workflows;

namespace YAPACS.RisServer.Services;

public class ReportStyleService(IRepository<ReportStyle, Guid> reportStyleRepository, IRepository<Exam, Guid> examRepository,
    ICurrentUserOrganization currentUserOrganization, IRepository<Report, Guid> reportRep) : DomainService, IReportStyleService, ITransientDependency
{
    private readonly IRepository<ReportStyle, Guid> _reportStyleRepository = reportStyleRepository;
    private readonly IRepository<Exam, Guid> _examRepository = examRepository;
    private readonly ICurrentUserOrganization _currentUserOrganization = currentUserOrganization;
    private readonly IRepository<Report, Guid> _reportRepository = reportRep;

    public async Task<WorkflowOutput> GetPrintOptionsAsync()
    {
        try
        {
            var query = await _reportStyleRepository.GetQueryableAsync();
            var list = query.Where(e => e.IsActive && e.Department.Oid == _currentUserOrganization.DepartmentId.Value)
                .GroupBy(e => e.StyleType)
                .Select(e => e.Key)
                .ToList();
            return new WorkflowOutput
            {
                Success = true,
                Data = list.Select(e => new
                {
                    Id = e,
                    Text = "打印" + e switch
                    {
                        ReportStyleType.Report => "报告单",
                        ReportStyleType.TempReport => "临时报告单",
                        ReportStyleType.ApplyForm => "申请单",
                        ReportStyleType.AppointmentForm => "预约单",
                        ReportStyleType.GuideForm => "指引单",
                        ReportStyleType.ReceiptForm => "回执单",
                        ReportStyleType.WaitingForm => "等候单",
                        ReportStyleType.BagSticker => "袋贴",
                        _ => "其他报告类型"
                    },
                    Icon = "print"
                }
                )
            };
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            return new WorkflowOutput { Success = false, Error = ex.Message };
        }
    }

    public async Task<IEnumerable> GetReportStylesAsync(Guid reportId)
    {
        var report = await _reportRepository.GetAsync(reportId);
        //查询数据
        var query = await _reportStyleRepository.GetQueryableAsync();
        query = query.Where(e => e.IsActive && e.StyleType == ReportStyleType.Report && e.Department == report.Exam.Department && e.DeviceType == report.Exam.DeviceType);
        var data = await AsyncExecuter.ToListAsync(
                query
                .OrderBy(e => e.Order)
                .ThenBy(e => e.CreationTime)
                .Select(e => new
                {
                    e.Oid,
                    e.DisplayName
                }));
        Dictionary<string, Guid> displayNames = [];
        foreach (var item in data)
        {
            string displayName = GetDisplayName(item.DisplayName);
            if (!displayNames.ContainsKey(displayName))
            {
                displayNames.Add(displayName, item.Oid);
            }
        }
        return displayNames.Select(e => new { Id = e.Value, Name = e.Key });
    }

    public async Task<ReportStyle> GetReportStyleAsync(Report report)
    {
        //获取图像个数
        int imageCount = report.ReportImages.Count;
        string displayName = GetDisplayName(report.ReportStyle.DisplayName);
        var query = await _reportStyleRepository.GetQueryableAsync();
        query = query.Where(e => e.IsActive
            && e.Department == report.Exam.Department
            && e.DeviceType == report.Exam.DeviceType
            && e.DisplayName.StartsWith(displayName))
            .OrderBy(e => e.DisplayName);

        var list = await AsyncExecuter.ToListAsync(query);
        var reportStyle = list.Where(e => e.DisplayName == displayName + "-" + imageCount).FirstOrDefault();
        if (reportStyle == null && imageCount == 0)
        {
            reportStyle = list.Where(e => e.DisplayName == displayName).FirstOrDefault();
        }
        if (reportStyle == null)
        {
            //顺序排序
            foreach (var item in list)
            {
                var arr = item.DisplayName.Split('-').ToList();
                if (arr.Count > 1 && int.TryParse(arr[^1], out int number))
                {
                    if (number >= imageCount)
                    {
                        reportStyle = item;
                    }
                }
            }
        }
        if (reportStyle == null)
        {
            //报表样式不能满足报告图像个数，选择图像最大的那一个
            reportStyle = list.OrderByDescending(e => e.DisplayName).FirstOrDefault();
        }
        return reportStyle;
    }

    public async Task<ReportStyle> GetTempReportStyleAsync(Report report)
    {
        var query = await _reportStyleRepository.GetQueryableAsync();
        query = query.Where(e => e.IsActive
            && e.Department == report.Exam.Department
            && e.DeviceType == report.Exam.DeviceType
            && e.StyleType == ReportStyleType.TempReport);
        return await AsyncExecuter.FirstOrDefaultAsync(query);
    }

    public string GetDisplayName(string displayName)
    {
        if (!string.IsNullOrWhiteSpace(displayName))
        {
            var arr = displayName.Split('-').ToList();
            if (arr.Count > 1 && int.TryParse(arr[^1], out _))
            {
                arr.RemoveAt(arr.Count - 1);
            }
            return string.Join('-', arr);
        }
        return null;
    }

    public async Task<object> GetReportStyleAsync(Guid reportStyleId)
    {
        var reportStyle = await _reportStyleRepository.GetAsync(reportStyleId);
        return new { Id = reportStyle.Oid, Name = GetDisplayName(reportStyle.DisplayName) };
    }
}
